<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>前端基础知识整理02 | 俊劫的学习基地</title>
    <meta name="generator" content="VuePress 1.7.1">
    <link rel="icon" href="/favicon.ico">
    <meta name="description" content="俊劫的学习基地是俊劫的个人博客，用于记录学习笔记、分享音乐、书籍、旅行等个人兴趣的站点。">
    <meta name="keywords" content="俊劫,俊劫的博客,博客,个人博客,vue,vuejs,vuepress,vuepress-theme-reco">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    
    <link rel="preload" href="/assets/css/0.styles.5f3e1891.css" as="style"><link rel="preload" href="/assets/js/app.070ad525.js" as="script"><link rel="preload" href="/assets/js/2.1d15da37.js" as="script"><link rel="preload" href="/assets/js/40.e59f0b3b.js" as="script"><link rel="preload" href="/assets/js/4.aab0e518.js" as="script"><link rel="prefetch" href="/assets/js/10.46adc9c3.js"><link rel="prefetch" href="/assets/js/11.4fa3a97f.js"><link rel="prefetch" href="/assets/js/12.d930e0cf.js"><link rel="prefetch" href="/assets/js/13.ac14e905.js"><link rel="prefetch" href="/assets/js/14.5db5f3a5.js"><link rel="prefetch" href="/assets/js/15.f912d397.js"><link rel="prefetch" href="/assets/js/16.dc881375.js"><link rel="prefetch" href="/assets/js/17.4b5e68db.js"><link rel="prefetch" href="/assets/js/18.e48da6e4.js"><link rel="prefetch" href="/assets/js/19.4a02bf41.js"><link rel="prefetch" href="/assets/js/20.8437ea4c.js"><link rel="prefetch" href="/assets/js/21.618c8e36.js"><link rel="prefetch" href="/assets/js/22.097f8d74.js"><link rel="prefetch" href="/assets/js/23.512dda35.js"><link rel="prefetch" href="/assets/js/24.2afceb8f.js"><link rel="prefetch" href="/assets/js/25.a7a02005.js"><link rel="prefetch" href="/assets/js/26.a79e1590.js"><link rel="prefetch" href="/assets/js/27.d0feb2c1.js"><link rel="prefetch" href="/assets/js/28.62b630e3.js"><link rel="prefetch" href="/assets/js/29.119f3256.js"><link rel="prefetch" href="/assets/js/3.8b40c051.js"><link rel="prefetch" href="/assets/js/30.5b11ce87.js"><link rel="prefetch" href="/assets/js/31.94ce824a.js"><link rel="prefetch" href="/assets/js/32.ed4f7508.js"><link rel="prefetch" href="/assets/js/33.c74281cf.js"><link rel="prefetch" href="/assets/js/34.ffb262b0.js"><link rel="prefetch" href="/assets/js/35.ada11000.js"><link rel="prefetch" href="/assets/js/36.edb96889.js"><link rel="prefetch" href="/assets/js/37.02fd03c3.js"><link rel="prefetch" href="/assets/js/38.4e0ec907.js"><link rel="prefetch" href="/assets/js/39.8cd27589.js"><link rel="prefetch" href="/assets/js/41.e3da8313.js"><link rel="prefetch" href="/assets/js/42.c847d1f4.js"><link rel="prefetch" href="/assets/js/43.13c84445.js"><link rel="prefetch" href="/assets/js/44.cbaa9acf.js"><link rel="prefetch" href="/assets/js/45.cb3a266d.js"><link rel="prefetch" href="/assets/js/46.0519c642.js"><link rel="prefetch" href="/assets/js/47.3373a57e.js"><link rel="prefetch" href="/assets/js/48.7efa5760.js"><link rel="prefetch" href="/assets/js/49.923721c8.js"><link rel="prefetch" href="/assets/js/5.07f41da3.js"><link rel="prefetch" href="/assets/js/50.839ac91d.js"><link rel="prefetch" href="/assets/js/51.f98cecb2.js"><link rel="prefetch" href="/assets/js/52.041f20b3.js"><link rel="prefetch" href="/assets/js/53.9464df60.js"><link rel="prefetch" href="/assets/js/54.a9ce67d2.js"><link rel="prefetch" href="/assets/js/55.9733d4b3.js"><link rel="prefetch" href="/assets/js/56.e67c1aa1.js"><link rel="prefetch" href="/assets/js/57.1335a8a7.js"><link rel="prefetch" href="/assets/js/58.83f617d8.js"><link rel="prefetch" href="/assets/js/59.b74c2845.js"><link rel="prefetch" href="/assets/js/6.dcf50b6e.js"><link rel="prefetch" href="/assets/js/60.6e3b00bd.js"><link rel="prefetch" href="/assets/js/61.cd335db9.js"><link rel="prefetch" href="/assets/js/62.ee277d48.js"><link rel="prefetch" href="/assets/js/63.2a34cfa5.js"><link rel="prefetch" href="/assets/js/64.a51989fe.js"><link rel="prefetch" href="/assets/js/65.3abfaea5.js"><link rel="prefetch" href="/assets/js/66.d4f35c55.js"><link rel="prefetch" href="/assets/js/67.2f070f74.js"><link rel="prefetch" href="/assets/js/68.c7da856f.js"><link rel="prefetch" href="/assets/js/69.6c15fcd4.js"><link rel="prefetch" href="/assets/js/7.10c46d97.js"><link rel="prefetch" href="/assets/js/70.68b6cf93.js"><link rel="prefetch" href="/assets/js/71.c49db210.js"><link rel="prefetch" href="/assets/js/72.7ffae8af.js"><link rel="prefetch" href="/assets/js/73.abb40ede.js"><link rel="prefetch" href="/assets/js/74.71723883.js"><link rel="prefetch" href="/assets/js/75.ab7e2e75.js"><link rel="prefetch" href="/assets/js/76.936112a6.js"><link rel="prefetch" href="/assets/js/8.ec9c3735.js"><link rel="prefetch" href="/assets/js/9.b555605d.js">
    <link rel="stylesheet" href="/assets/css/0.styles.5f3e1891.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container have-rightmenu" data-v-f848d4e8><div class="global-loading-wrapper" data-v-2c41f3eb data-v-f848d4e8 data-v-f848d4e8><div class="loader-main" data-v-2c41f3eb><img src="/assets/img/loading.a592e2e5.jpg" alt="loading" data-v-2c41f3eb></div></div> <div class="hide" data-v-f848d4e8><header class="navbar" data-v-f848d4e8><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/img/logo.png" alt="俊劫的学习基地" class="logo"> <span class="site-name">俊劫的学习基地</span></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">选择模式</h4> <ul class="color-mode-options"><li class="dark">深色模式</li><li class="light active">浅色模式</li><li class="read">阅读模式</li></ul></div></div></div> <div class="search-box"><i class="iconfont reco-search"></i> <input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <ul class="suggestions" style="display:none;"></ul></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/" class="nav-link"><i class="iconfont reco-home"></i>首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i></i>前端
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>文档教程</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/web/docs/imooc/wiki/" class="nav-link"><i class="iconfont reco-blog"></i>慕课教程
</a></li><li class="dropdown-subitem"><a href="/web/docs/es6/" class="nav-link"><i class="iconfont reco-blog"></i>ES6 入门教程
</a></li><li class="dropdown-subitem"><a href="/web/docs/wangdoc/javascript/" class="nav-link"><i class="iconfont reco-blog"></i>网道-JavaScript 教程
</a></li><li class="dropdown-subitem"><a href="/web/docs/angular/" class="nav-link"><i class="iconfont reco-blog"></i>Angular 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/react/" class="nav-link"><i class="iconfont reco-blog"></i>React 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/vue/" class="nav-link"><i class="iconfont reco-blog"></i>Vue 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/node/" class="nav-link"><i class="iconfont reco-blog"></i>Node 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/babel/" class="nav-link"><i class="iconfont reco-blog"></i>Babel 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/webpack/" class="nav-link"><i class="iconfont reco-blog"></i>Webpack 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/typescript/" class="nav-link"><i class="iconfont reco-blog"></i>TypeScript 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/runoob/" class="nav-link"><i class="iconfont reco-blog"></i>菜鸟教程
</a></li><li class="dropdown-subitem"><a href="/web/docs/docschina/" class="nav-link"><i class="iconfont reco-blog"></i>印记中文
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-api"></i>索引
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link"><i class="iconfont reco-category"></i>分类
</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link"><i class="iconfont reco-tag"></i>标签
</a></li><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link"><i class="iconfont reco-date"></i>归档
</a></li></ul></div></div><div class="nav-item"><a href="/bookshop/message-board/" class="nav-link"><i class="iconfont reco-suggestion"></i>留言板
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>关于
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>联系</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://github.com/alexwjj" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-github"></i>GitHub
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="/bookshop/linkme/" class="nav-link"><i class="iconfont reco-account"></i>关于我
</a></li></ul></li><li class="dropdown-item"><h4>博客</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://github.com/alexwjj/alexwjj.github.io" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-document"></i>本站源码
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://alexwjj.github.io/old-blog" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-document"></i>老版博客
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li><li class="dropdown-item"><h4>其他</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/bookshop/friendslink/" class="nav-link"><i class="iconfont reco-friend"></i>友情链接
</a></li></ul></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask" data-v-f848d4e8></div> <aside class="sidebar" data-v-f848d4e8><div class="personal-info-wrapper" data-v-34faaed8 data-v-f848d4e8><img src="/img/logo.png" alt="author-avatar" class="personal-img" data-v-34faaed8> <div class="author" data-v-34faaed8>
    俊劫
  </div> <div class="personal-info-details" data-v-34faaed8><div data-v-34faaed8>文章：<span data-v-34faaed8>54</span></div> <div data-v-34faaed8>地点：<span data-v-34faaed8>canton</span></div></div> <div class="slogan" data-v-34faaed8>
    just do it
  </div> <!----></div> <nav class="nav-links"><div class="nav-item"><a href="/" class="nav-link"><i class="iconfont reco-home"></i>首页
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i></i>前端
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>文档教程</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/web/docs/imooc/wiki/" class="nav-link"><i class="iconfont reco-blog"></i>慕课教程
</a></li><li class="dropdown-subitem"><a href="/web/docs/es6/" class="nav-link"><i class="iconfont reco-blog"></i>ES6 入门教程
</a></li><li class="dropdown-subitem"><a href="/web/docs/wangdoc/javascript/" class="nav-link"><i class="iconfont reco-blog"></i>网道-JavaScript 教程
</a></li><li class="dropdown-subitem"><a href="/web/docs/angular/" class="nav-link"><i class="iconfont reco-blog"></i>Angular 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/react/" class="nav-link"><i class="iconfont reco-blog"></i>React 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/vue/" class="nav-link"><i class="iconfont reco-blog"></i>Vue 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/node/" class="nav-link"><i class="iconfont reco-blog"></i>Node 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/babel/" class="nav-link"><i class="iconfont reco-blog"></i>Babel 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/webpack/" class="nav-link"><i class="iconfont reco-blog"></i>Webpack 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/typescript/" class="nav-link"><i class="iconfont reco-blog"></i>TypeScript 文档
</a></li><li class="dropdown-subitem"><a href="/web/docs/runoob/" class="nav-link"><i class="iconfont reco-blog"></i>菜鸟教程
</a></li><li class="dropdown-subitem"><a href="/web/docs/docschina/" class="nav-link"><i class="iconfont reco-blog"></i>印记中文
</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-api"></i>索引
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link"><i class="iconfont reco-category"></i>分类
</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link"><i class="iconfont reco-tag"></i>标签
</a></li><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link"><i class="iconfont reco-date"></i>归档
</a></li></ul></div></div><div class="nav-item"><a href="/bookshop/message-board/" class="nav-link"><i class="iconfont reco-suggestion"></i>留言板
</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title"><i class="iconfont reco-message"></i>关于
    </span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>联系</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://github.com/alexwjj" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-github"></i>GitHub
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="/bookshop/linkme/" class="nav-link"><i class="iconfont reco-account"></i>关于我
</a></li></ul></li><li class="dropdown-item"><h4>博客</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://github.com/alexwjj/alexwjj.github.io" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-document"></i>本站源码
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://alexwjj.github.io/old-blog" target="_blank" rel="noopener noreferrer" class="nav-link external"><i class="iconfont reco-document"></i>老版博客
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li><li class="dropdown-item"><h4>其他</h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/bookshop/friendslink/" class="nav-link"><i class="iconfont reco-friend"></i>友情链接
</a></li></ul></li></ul></div></div> <!----></nav> <ul class="sidebar-links"><li><a href="/pages/74b89136d37c/" class="sidebar-link">【面试】2020年底面经</a></li><li><a href="/pages/ac34940436a4a/" class="sidebar-link">前端基础知识整理01</a></li><li><a href="/pages/aa9d140ec6135/" aria-current="page" class="active sidebar-link">前端基础知识整理02</a></li><li><a href="/pages/3cea8c7d5577f/" class="sidebar-link">xdm 来当当前端面试官</a></li><li><a href="/pages/9de40adc21b12/" class="sidebar-link">前端基础 - 手写系列</a></li><li><a href="/pages/f15a7725f87e7/" class="sidebar-link">【分享】2021新鲜面经和资源分享</a></li><li><a href="/pages/a336385364f8/" class="sidebar-link">【面试】前端求职之路</a></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper bg-style-1"><div class="articleInfo-wrap" data-v-13f19dad><div class="articleInfo" data-v-13f19dad><ul class="breadcrumbs" data-v-13f19dad><li data-v-13f19dad><a href="/" title="首页" class="fa fa-laptop-house router-link-active" data-v-13f19dad></a></li> <li data-v-13f19dad><a href="/categories/?category=%E9%9D%A2%E8%AF%95%E7%9B%B8%E5%85%B3" title="分类" data-v-13f19dad>面试相关</a></li> <!----> <!----></ul> <div class="info" data-v-13f19dad><div title="作者" class="author fa fa-user" data-v-13f19dad><a href="javascript:;" data-v-13f19dad>俊劫</a></div> <div title="创建时间" class="date fa fa-calendar-alt" data-v-13f19dad><a href="javascript:;" data-v-13f19dad>2020/05/19 00:00:00</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-content"></div></div></div> <h1><img src="">
            前端基础知识整理02
          </h1> <div class="theme-vdoing-content content__default"><blockquote><p>进阶版 要多练习 😈😈😈</p></blockquote> <h2 id="好文"><a href="#好文" class="header-anchor">#</a> 好文</h2> <ul><li><a href="https://mp.weixin.qq.com/s/hN2yTtFLyFBWmOrKF-E8lQ" target="_blank" rel="noopener noreferrer">webpack 打包优化<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/6865957891988258823" target="_blank" rel="noopener noreferrer">web打印，一篇搞定<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/6844903845227659271" target="_blank" rel="noopener noreferrer">正则表达式不要背<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/6844903896637259784" target="_blank" rel="noopener noreferrer">一个合格(优秀)的前端都应该阅读这些文章<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/6844903638389915661" target="_blank" rel="noopener noreferrer">Vue源码阅读前必须知道javascript的基础内容<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/6844903926110617613" target="_blank" rel="noopener noreferrer">灵活运用CSS开发技巧<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/6844903767926636558" target="_blank" rel="noopener noreferrer">一篇文章构建你的 NodeJS 知识体系<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/6844903679162581005" target="_blank" rel="noopener noreferrer">vue插件开发、文档书写、github发布、npm包发布一波流<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li> <li><a href="https://juejin.im/post/6844904116339261447" target="_blank" rel="noopener noreferrer">2020年前端面试复习必读文章<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul> <h2 id="_1-注意点"><a href="#_1-注意点" class="header-anchor">#</a> 1.注意点</h2> <ul><li>IOS 无法识别<strong>yy-mm-dd</strong>这种带 - 的时间格式'</li> <li><strong>typeof null === 'object':</strong> 在 JS 的最初版本中，使用的是 32 位系统，为了性能考虑使用低位存储了变量的类型信息，000 开头代表是对象，然而 null 表示为全零，所以将它错误的判断为 object 。</li> <li>原生<strong>sort</strong>使用的是哪些排序算法？插入排序和快速排序结合的排序算法</li> <li><strong>数组扁平化</strong>：arr.toString().split(',')，注意返回数组中的数据类型</li> <li>求<strong>最大值</strong> Math.max.apply(null, arr) Math.max.call(null, ...arr)</li> <li><strong>async函数</strong>就是将 Generator 函数的星号（*）替换成async，将yield替换成await。</li> <li>vue.js中组件<strong>export default 中name</strong>的三种作用：vue-tools调试，keep-alive识别组件，组件模板递归调用自己</li> <li>Object.prototype.toString.call(null) === &quot;[object Null]&quot;</li></ul> <h2 id="_2-判断一个数组的类型"><a href="#_2-判断一个数组的类型" class="header-anchor">#</a> 2.判断一个数组的类型</h2> <p>1.判断是否具有数组某些方法
<code>if(arr.sort()){}</code></p> <p>2.instanceof(某些IE版本不正确)<code>arr instanceof Array</code></p> <p>3.<code>Array.isArray()</code></p> <p>4.<code>Object.prototype.toString.call(arr);</code> // '[object Array]'</p> <p>5.constructor方法<code>arr.constructor === Array</code></p> <p>6.通用办法</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>var isArray = Array.isArray || function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
};
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h2 id="_3-变量提升-函数提升"><a href="#_3-变量提升-函数提升" class="header-anchor">#</a> 3.变量提升 &amp;&amp; 函数提升</h2> <ul><li>js查找变量 先在 <strong>当前作用域中查找</strong>  存在则返回，不存在则向上查找</li> <li><strong>函数的优先权</strong>是最高的，它永远被提升至作用域最顶部，然后才是函数表达式和变量按顺序执行
变量提升是人为实现的问题，而函数提升在当初设计时是有目的的。</li></ul> <h2 id="_4-事件"><a href="#_4-事件" class="header-anchor">#</a> 4.事件</h2> <ul><li>事件委托：让利用事件冒泡的原理，让自己的所触发的事件，让他的父元素代替执行！</li> <li>事件捕获阶段(与冒泡相反)）=&gt;目标元素阶段=&gt;事件冒泡阶段</li></ul> <h3 id="addeventlistener"><a href="#addeventlistener" class="header-anchor">#</a> addEventListener</h3> <ul><li>该函数的第三个参数可以是布尔值，也可以是对象。对于布尔值 useCapture 参数来说，该参数<strong>默认值为 false</strong> 。useCapture 决定了注册的事件是捕获事件(true)还是冒泡事件（false）。</li></ul> <p>如果一个节点中的子节点是动态生成的，那么子节点需要注册事件的话应该注册在父节点上</p> <ul><li>阻止事件冒泡：event.stopPropagation()</li> <li>阻止默认事件：event.preventDefault()</li></ul> <h3 id="event-loop"><a href="#event-loop" class="header-anchor">#</a> Event loop</h3> <p>JS 是门<strong>非阻塞单线程语言</strong>,如果 JS 是门多线程的语言话，我们在多个线程中处理 DOM 就可能会发生问题（一个线程中新加节点，另一个线程中删除节点），当然可以引入读写锁解决这个问题</p> <h3 id="event-loop-顺序是这样的"><a href="#event-loop-顺序是这样的" class="header-anchor">#</a> Event loop 顺序是这样的</h3> <p>1.执行同步代码 // console</p> <p>2.执行栈为空，查询是否有微任务需要执行</p> <p>3.执行所有微任务 // Promise.then</p> <p>4.执行宏任务中的异步代码 // setTimeout</p> <p>5.然后开始下一轮 Event loop，</p> <h3 id="任务队列"><a href="#任务队列" class="header-anchor">#</a> 任务队列</h3> <p>不同的任务源会被分配到不同的 Task 队列中，任务源可以分为 微任务（microtask） 和 宏任务（macrotask）
微任务包括 process.nextTick ，<strong>promise</strong> ，Object.observe ，MutationObserver
宏任务包括 script ，<strong>setTimeout</strong> ，<strong>setInterval</strong> ，setImmediate ，I/O ，UI rendering</p> <h2 id="_5-http"><a href="#_5-http" class="header-anchor">#</a> 5.HTTP</h2> <p><strong>简单快速</strong>：客户向服务器请求服务时，只需传送请求方法和路径</p> <p><strong>灵活</strong>：HTTP允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记</p> <p><strong>无连接</strong>：无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求，并收到客户的应答后，即断开连接 (深入-持久连接、管线化)</p> <p><strong>无状态</strong>：HTTP协议是无状态协议( Cookie 的出现)</p> <h3 id="http-请求方法"><a href="#http-请求方法" class="header-anchor">#</a> http 请求方法</h3> <p><strong>HTTP1.0</strong>定义了三种请求方法： GET, POST 和 HEAD方法。</p> <p><strong>HTTP1.1</strong>新增了五种请求方法：OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。</p> <h3 id="一般的http连接都是"><a href="#一般的http连接都是" class="header-anchor">#</a> 一般的http连接都是：</h3> <ul><li>三次握手建立连接，</li> <li>发送http请求报文，获取响应报文，</li> <li>通过四次挥手，中断连接</li> <li>HTTP1.1中connection<strong>默认开启keep-alive</strong>，就不需要连续的建立然后中断</li></ul> <h2 id="http-状态码"><a href="#http-状态码" class="header-anchor">#</a> http 状态码</h2> <ul><li>1xx指示信息，请求已接收，继续处理</li> <li>2xx成功，请求已成功</li> <li>3xx重定向，要完成请求必须要进行下一步操作</li> <li>4xx客户端错误，请求有语法错误或无法实现</li> <li>5xx服务端错误，服务器未能实现合法的请求</li></ul> <h2 id="_6-浏览器渲染页面的过程"><a href="#_6-浏览器渲染页面的过程" class="header-anchor">#</a> 6.浏览器渲染页面的过程</h2> <p>从耗时的角度，浏览器请求、加载、渲染一个页面，时间花在下面五件事情上：</p> <ul><li>DNS 查询</li> <li>TCP 连接</li> <li>HTTP 请求即响应</li> <li>服务器响应</li> <li>客户端渲染</li></ul> <p>第五个部分，即浏览器对内容的渲染，这一部分（渲染树构建、布局及绘制），又可以分为下面五个步骤：</p> <ul><li>处理 HTML 标记并构建 DOM 树。</li> <li>处理 CSS 标记并构建 CSSOM 树。</li> <li>将 DOM 与 CSSOM 合并成一个渲染树。</li> <li>根据渲染树来布局，以计算每个节点的几何信息。</li> <li>将各个节点绘制到屏幕上。</li></ul> <h2 id="_7-原型"><a href="#_7-原型" class="header-anchor">#</a> 7.原型</h2> <p>所有引用类型（数组、对象、函数）都有一个__proto__隐式原型属性，属性值是一个普通对象。 此外，<strong>Object.prototype.__proto__指向null</strong></p> <p>所有函数都有一个prototype显式原型属性，属性值是一个普通对象。</p> <p>Function.prototype.bind()没有prototype属性</p> <p>所有引用类型（数组、对象、函数）的__proto__执行它的构造函数的prototype属性</p> <h2 id="_8-迭代方法"><a href="#_8-迭代方法" class="header-anchor">#</a> 8. 迭代方法</h2> <ul><li>every 查询数组是否每一项都满足条件</li> <li>some 查询数组中是否有满足条件的项</li> <li>filter 过滤，返回true的项组成的数组</li> <li>map 对每一项运行给定函数，返回每次函数调用结果组成的数组</li> <li>forEach 对每一项运行给定函数，无返回值</li> <li>reduce 让数组的前一项和后一项做某种计算，累计最终值</li> <li>find 查找某一项</li></ul> <div class="language- line-numbers-mode"><pre class="language-text"><code>var numbers = [1,2,3,4,5,4,3,2,1];
numbers.every(function(item,index,array){
    return item&gt;2;
})  // false
numbers.some(function(item,index,array){
    return item&gt;2;
})  // true
numbers.filter(function(item,index,array){
    return item&gt;2;
})  // [3,4,5,4,3]
numbers.map(function(item,index,array){
    return item*2;
})  // [2,4,6,8,10,8,6,4,2]
numbers.forEach(function(item,index,array){
    // 执行某些操作
})  // 无返回值
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><h2 id="_9-new操作符具体干了什么-理解构造函数相当于一个模板"><a href="#_9-new操作符具体干了什么-理解构造函数相当于一个模板" class="header-anchor">#</a> 9.new操作符具体干了什么？ （理解构造函数相当于一个模板）</h2> <ul><li>创建一个空对象</li> <li>将对象的__proto指向构造函数的原型prototype</li> <li>执行构造函数中的代码，传递参数，并将this指向这个对象</li> <li>返回对象</li></ul> <h2 id="_10-继承"><a href="#_10-继承" class="header-anchor">#</a> 10.继承</h2> <p>ES5实现思路就是将子类的原型设置为父类的原型</p> <p>在 ES6 中，我们可以通过 class 语法**(本质也是原型链继承)**</p> <h2 id="_11-闭包"><a href="#_11-闭包" class="header-anchor">#</a> 11.闭包</h2> <p><strong>闭包指有权访问另一个函数内部变量的函数</strong>，当在函数内部定义了其他函数，也就创建了闭包</p> <p>想要访问一个f1内的变量，在f1内在创建一个函数f2，将f2的值作为返回值，在调用f1时就能访问到f1里面的局部变量</p> <ul><li><p>场景1：使用函数内部变量</p></li> <li><p>场景2：保存变量在内存中</p></li> <li><p>内存泄露
闭包会引用包含函数的整个变量对象，如果闭包的作用域链中保存着一个HTML元素，那么就意味着该元素无法被销毁。所以我们有必要在对这个元素操作完之后<strong>主动销毁。 = null</strong></p></li> <li><p>函数内部定时器
当函数内部的定时器引用了外部函数的变量对象时，该变量对象不会被销毁。</p></li></ul> <p><strong>应用场景</strong></p> <ul><li>设计私有的变量和方法
模块模式：为单例创建私有的变量和方法</li></ul> <p>单例：指的是只有一个实例的对象。一般以对象字面量的方式来创建一个单例对象。</p> <p><strong>匿名函数最大的用途是创建闭包</strong>，并且还可以构建命名空间，以减少全局变量的使用。从而使用闭包模块化代码，减少全局变量的污染。</p> <p><img src="https://user-gold-cdn.xitu.io/2020/4/11/17167b11438a46b5?w=800&amp;h=522&amp;f=png&amp;s=28549" alt="">
在这段代码中函数 addEvent 和 removeEvent 都是局部变量，但我们可以通过全局变量 objEvent 使用它，这就大大减少了全局变量的使用，增强了网页的安全性。</p> <ul><li>经典面试题，循环中使用闭包解决 var 定义函数的问题</li></ul> <div class="language- line-numbers-mode"><pre class="language-text"><code>for ( var i=1; i&lt;=5; i++) {
	setTimeout( function timer() {
		console.log( i );
	}, i*1000 );
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>首先因为 setTimeout 是个异步函数，所有会先把循环全部执行完毕，这时候 i 就是 6 了，所以会输出5个6。</p> <p>解决办法两种，第一种使用闭包</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>for (var i = 1; i &lt;= 5; i++) {
  (function(j) {
    setTimeout(function timer() {
      console.log(j);
    }, j * 1000);
  })(i);
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p>第二种就是使用 setTimeout 的第三个参数</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>for ( var i=1; i&lt;=5; i++) {
	setTimeout( function timer(j) {
		console.log( j );
	}, i*1000, i);
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p>第三种就是使用 let 定义 i 了</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>for ( let i=1; i&lt;=5; i++) {
	setTimeout( function timer() {
		console.log( i );
	}, i*1000 );
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h2 id="_12-bom对象"><a href="#_12-bom对象" class="header-anchor">#</a> 12.BOM对象</h2> <div class="language- line-numbers-mode"><pre class="language-text"><code>window JS最顶层对象
location 浏览器当前URL信息
navigator 浏览器本身信息
screen 客户端屏幕信息
history 浏览器访问历史信息
window对象的方法
alert(),prompt(),confirm(),open(),close(),print(),focus(),blur(),moveBy(),moveTo(),resizeBy(),resizeTo(),scrollBy(),scrollTo(),setInterval(),setTimeout(),clearInterval(),clearTimeout()
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><h2 id="_13-拆解url的各部分"><a href="#_13-拆解url的各部分" class="header-anchor">#</a> 13.拆解url的各部分</h2> <p><strong>使用location的属性</strong></p> <div class="language- line-numbers-mode"><pre class="language-text"><code>href 完整url地址
protocol 协议
host 主机名+端口号
hostname 主机名
port 端口号
pathname 相对路径
hash #锚点
search ?查询字符串
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h2 id="_14-为什么操作dom慢"><a href="#_14-为什么操作dom慢" class="header-anchor">#</a> 14.为什么操作DOM慢？</h2> <p>因为DOM属于渲染引擎的东西，JS又是JS引擎的东西，当我们<strong>通过JS操作DOM</strong>的时候，涉及到<strong>两个线程间的通信</strong>，而且操作DOM可能会带来<strong>重绘回流</strong>的情况，所以就导致了性能问题。</p> <p>DOM对象本身也是一个js对象，操作了这个对象后，会触发一些浏览器行为，比如布局（layout）和绘制（paint）。
重绘是当节点改变样式而不影响布局，回流是当布局或几何属性需要改变
回流必定会发生重绘，回流的成本比重绘高</p> <p><strong>虚拟dom</strong>
在浏览器内存中进行渲染</p> <h2 id="_15-dom"><a href="#_15-dom" class="header-anchor">#</a> 15.Dom</h2> <div class="language- line-numbers-mode"><pre class="language-text"><code>document.querySelector // 返回第一个匹配的元素
document.querySelectorAll  // 返回匹配的所有元素
// 获取文档中所有 class=&quot;example&quot; 的 &lt;p&gt; 元素
var x = document.querySelectorAll(&quot;p.example&quot;); 
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p><strong>DOM事件</strong>
DOM事件的级别</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>DOM0 element.onclick=function(){}
DOM2 element.addEventListener('click',function(){},false)
DOM3 element.addEventListener('keyup',function(){},false)
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>DOM0级事件就是将一个函数赋值给一个事件处理属性，缺点在于一个处理程序无法同时绑定多个处理函数。</p> <p>DOM2级事件运行给一个程序添加多个处理函数，定义了<strong>addEventListener</strong>和<strong>removeEventListener</strong>两个方法，分别用于绑定和解绑事件，方法包含三个参数分别是绑定的事件处理的属性名称，处理函数，<strong>是否在捕获时执行事件</strong></p> <p>IE8以下使用attachEvent和detachEvent实现，不需要传入第三个参数，因为IE8以下只支持<strong>冒泡型事件</strong></p> <div class="language- line-numbers-mode"><pre class="language-text"><code>btn.attachEvent('onclick', showFn);
btn.detachEvent('onclick', showFn);
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>DOM3级事件是在DOM2级事件的基础上添加很多事件类型如load,scroll,blur,focus,dbclick,mouseup,mousewheel,textInput,keydown,keypress，同时也允许使用者自定义一些事件</p> <h2 id="_16-js获取盒模型宽高"><a href="#_16-js获取盒模型宽高" class="header-anchor">#</a> 16.js获取盒模型宽高</h2> <p>最常用，兼容性最好** dom.offsetWidth/offsetHeight**</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>offsetWidth/offsetHeight,clientWidth/clientHeight与srcollWidth/scrollHeight的区别
offsetWidth/offsetHeight返回包含content+padding+border 全部宽高
clientWidth/clientHeight返回包含content+padding，如果有滚动条，也不包含滚动条
scrollWidth/scrollHeight返回包含content+paddin+溢出内容的尺寸
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><h2 id="_17-ajax"><a href="#_17-ajax" class="header-anchor">#</a> 17.Ajax</h2> <div class="language- line-numbers-mode"><pre class="language-text"><code>// 创建XMLHTTPRequest对象
var xhr = new XMLHttpRequest();
// 创建一个新的http请求
xhr.open(&quot;get&quot;, url, true)
// 设置响应HTTP请求状态变化的函数
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            // 获取异步调用返回的数据
            alert(xhr.responseText)
        }
    }
}
// 发送HTTP请求
xhr.send(null);
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br></div></div><p>状态码readyState说明：0：未初始化，未调用send()；1：已调用send()，正在发生请求；2:send()方法执行完毕，已经接收到全部响应内容；3：正在解析响应内容；4：解析完成，可以在客户端调用了</p> <h2 id="_18-跨域"><a href="#_18-跨域" class="header-anchor">#</a> 18.跨域</h2> <p>跨域指通过JS在不同的域之间进行数据传入或通信。 <strong>协议，域名，端口</strong>有一个不同就是跨域
同源策略是为了防止<strong>CSRF攻击</strong>，它是利用用户的登录态发起恶意请求。</p> <p><strong>解决跨域方式</strong></p> <ul><li>JSONP使用简单，兼容性不错但仅限GET请求</li> <li>CORS服务器端设置Access-Control-Origin开启CORS，该属性表明哪些域名可以访问资源。</li> <li>document.domain 只适用于二级域名相同，a.test.com。在页面添加docuemtn.domain = 'test.com'表示二级域名相同即可跨域</li> <li>postMessage 通常用于获取嵌入页面(iframe)的第三方页面数据，一个页面发送消息，另一个页面判断来源并接收消息</li></ul> <div class="language- line-numbers-mode"><pre class="language-text"><code>// 发送消息
window.parent.postMessage('message', 'http://www.test.com')
// 接收消息
let mc=new MessageChannel()
mc.addEventListener('message', event =&gt; {
    let origin = event.origin || event.originalEvent.origin;
    if(origin === 'http://www.test.com'){
        console.log('验证通过')
    }
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><h2 id="_19-server-worker的工作-缓存文件"><a href="#_19-server-worker的工作-缓存文件" class="header-anchor">#</a> 19.Server Worker的工作？   缓存文件</h2> <p>与缓存进行交互，当用户请求缓存中的东西时，Service Worker能立刻从缓存中获取数据不通过外部https调用,传输协议必须为https，目前该技术通常用来做缓存文件，提高<strong>首屏速度</strong></p> <h2 id="_20-indexdb"><a href="#_20-indexdb" class="header-anchor">#</a> 20.indexDB</h2> <p>Cookie 的大小不超过4KB，且每次请求都会发送回服务器；LocalStorage 在 2.5MB 到 10MB 之间（各家浏览器不同），而且不提供搜索功能，不能建立自定义的索引。<strong>indexDB都可以做到，存储无上限</strong></p> <p>****21.浅拷贝 &amp;&amp; 深拷贝
栈（stack）为自动分配的内存空间，它由系统自动释放，存放<strong>基本类型</strong>（不可改变））</p> <p>堆（heap）则是动态分配的内存，大小不定也不会自动释放，存放<strong>引用类型</strong>。</p> <p>基本类型的比较是值的比较，只要它们的值相等就认为他们是相等的</p> <p>引用类型的比较是引用的比较，比较是否指向同一块堆内存</p> <p>基本数据类型的赋值（=）是在内存中新开辟一段栈内存，然后再把再将值赋值到新的栈中。</p> <p>引用类型的赋值是传址。只是<strong>改变指针的指向</strong></p> <p>深拷贝：将 B 对象拷贝到 A 对象中，包括 B 里面的子对象，</p> <p>浅拷贝：将 B 对象拷贝到 A 对象中，但不包括 B 里面的子对象</p> <p>深拷贝：</p> <ul><li>JSON.parse(JSON.stringify(Obj))对象中存在循环对象无法处理</li> <li>Object.create()</li> <li>Object.assign() 对象只有一层</li> <li>obj2 = _.cloneDeep(obj1) 复杂情况的深拷贝使用lodash实现
浅拷贝：</li> <li>= 赋值</li> <li>...  es6展开符</li> <li>object.assign()  对象有多层</li></ul> <h2 id="_21-flex-rem-vw-wh"><a href="#_21-flex-rem-vw-wh" class="header-anchor">#</a> 21.flex + rem + vw wh</h2> <p>rem 自动转换：使用lib-flexible和px2rem</p> <ul><li>flex
flex 是 flex-grow（放大），flex-shrink （缩放）和 flex-based （基本）的缩写  默认<strong>flex:0 1 auto</strong>;</li></ul> <p>flex-grow 控制的是 flex 项的拉伸比例，而不是占据 flex 容器的空间比例。当设置为 0 时，该 flex 项将不会被拉伸去填补剩余空间
两个项的比例是 1:2，意思是在被拉伸时，第一个 flex 项将占用 1/3，而第二个 flex 项将占据余下的空间。</p> <p>flex-shrink相反</p> <p>flex-based 自定义元素宽度，200px ,10%都行</p> <p>以下6个属性设置在容器上。</p> <ul><li>flex-direction</li> <li>flex-wrap</li> <li>flex-flow</li> <li>justify-content</li> <li>align-items</li> <li>align-content</li></ul> <p>以下6个属性设置在项目上。</p> <ul><li>order</li> <li>flex-grow</li> <li>flex-shrink</li> <li>flex-basis</li> <li>flex</li> <li>align-self</li></ul> <h3 id="rem"><a href="#rem" class="header-anchor">#</a> rem</h3> <p>计算方式： 设计稿px  /  根节点px  =  真实rem</p> <p>flexible实际上就是能过JS来动态改写meta标签，动态改写</p><meta>标签<p></p> <p>给<code>&lt;html&gt;</code>元素添加data-dpr属性，并且动态改写data-dpr的值
给<code>&lt;html&gt;</code>元素添加font-size属性，并且动态改写font-size的值</p> <h3 id="vh-vw"><a href="#vh-vw" class="header-anchor">#</a> vh vw</h3> <p>vh vw是相对视口（viewport）的宽度而定的，长度等于视口宽度的1/100，当前屏幕可见高度的1%。 假如浏览器的宽度为200px，那么1vw就等于2px（200px/100）。</p> <p>vh是相对视口（viewport）的高度而定的，长度等于视口高度的1/100。 假如浏览器的高度为500px，那么1vh就等于5px（500px/100
calc(100vh - 10px)  表示整个浏览器窗口高度减去10px的大小</p> <h2 id="_22-js-结果舍入运算"><a href="#_22-js-结果舍入运算" class="header-anchor">#</a> 22.js 结果舍入运算</h2> <div class="language- line-numbers-mode"><pre class="language-text"><code>x.toFixed( num)  将x保留num位小数  银行家舍入：四舍六入五考虑，五后非零就进一，五后为零看奇偶，五前为偶应舍去，五前为奇要进一。四舍六入五取偶
Math.round(x)   四舍五入 round() 方法可把一个数字舍入为最接近的整数
parseInt() 丢弃小数部分,保留整数部分
Math.ceil() 向上取整,有小数就整数部分加1 
Math.floor()  向下取整
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><h2 id="_23-this"><a href="#_23-this" class="header-anchor">#</a> 23. this</h2> <ul><li>this指向</li></ul> <p>定义：this的指向在函数定义的时候是确定不了的，只有<strong>函数执行</strong>的时候才能确定this到底指向谁，实际上this的最终指向的是那个<strong>调用它的对象</strong></p> <p>总结：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>1.在普通函数内部，this的指向是window
2.在方法内部，this的指向是方法的拥有者。
3.在箭头函数内部，this指向是创建箭头函数时所在的环境中的this指向的值。
4.在对象中，this指向当前对象
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>这里的this指向会发生改变</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>5.计时器中的this
6.回调函数中的this
7.事件处理函数中的this指向事件的绑定者
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h2 id="_24-安全"><a href="#_24-安全" class="header-anchor">#</a> 24.安全</h2> <p><strong>XSS</strong></p> <p>XSS 通过修改 HTML 节点或者执行 JS 代码来攻击网站。
最普遍的做法是转义（replace）输入输出的内容，对于引号，尖括号，斜杠进行转义。显示富文本的采用白名单过滤的方式</p> <p>CSP CSP 本质上也是建立白名单，通常可以通过 HTTP Header 中的 Content-Security-Policy 来开启 CSP</p> <p><strong>CSRF</strong></p> <p>CSRF 就是利用用户的登录态发起恶意请求。
防御：1.请求时附带验证信息，比如验证码或者 token
2.验证 Referer:对于需要防范 CSRF 的请求，我们可以通过验证 Referer 来判断该请求是否为第三方网站发起的。
3.Token:服务器下发一个随机 Token，每次发起请求时将 Token 携带上，服务器验证 Token 是否有效
4.信息加密</p> <p><strong>SQL注入</strong></p> <p>就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串，欺骗服务器执行恶意的SQL命令。 攻击者通过在应用程序预先定义好的SQL语句结尾加上额外的SQL语句元素，欺骗数据库服务器执行非授权的查询,篡改命令。</p> <p>参数化查询已被视为最有效的可防御SQL注入攻击的防御方式。目前主流的ORM 框架都内置支持并且推荐使用这种方式进行持久层封装。
参数化查询是指在设计与数据库链接并访问数据时，在需要填入数值或数据的地方，使用参数来给值。</p> <h2 id="_25-为什么不推荐使用setinterval"><a href="#_25-为什么不推荐使用setinterval" class="header-anchor">#</a> 25.为什么不推荐使用setInterval</h2> <p>js 的执行原理：js引擎是单线程的，主要分为主线程和事件队列，同步操作是在主线程上执行，而异步操作的函数会先放在事件队列当中，等到js主线程空闲了，才会去事件队列取出放到主线程执行。定时器是属于异步事件，参数里面设置的时间，并不是延迟多少秒去执行回调函数，这个时间代表的是延迟多少秒，把回调函数放到异步队列，等待主线程空闲再被执行。</p> <p>如果当事件队列当中，已经存在了定时器的回调函数，即使已经到了规定的间隔时间，也不会再把这个时间点的定时器回调函数放到事件队列当中，定时器依旧运行。当下一个约定时间又到了，如果事件队列当中依然存在定时器的回调函数，这个时间点的定时器回调函数也不会放进事件队列…</p> <h2 id="_26-中文版chrome浏览器不支持12px以下字体的解决方案"><a href="#_26-中文版chrome浏览器不支持12px以下字体的解决方案" class="header-anchor">#</a> 26.中文版Chrome浏览器不支持12px以下字体的解决方案</h2> <p>一般解决方案是禁止webkit浏览器配置调整网页的字体大小。如下CSS定义方式：
<code>.classstyle{ -webkit-text-size-adjust:none; font-size:9px; }</code></p> <h2 id="_27-getelementby-和-queryselector-区别"><a href="#_27-getelementby-和-queryselector-区别" class="header-anchor">#</a> 27.getElementBy*  和 querySelector 区别</h2> <p>getElementById / querySelector 这两个获取到的都是dom节点，结果没有区别。</p> <p>getElement* 的实时性体现在返回集合的时候，我们知道getElementsBy*和querySelectorAll返回的都是一个节点集合，类似于数组，两种方法的区别就在于<strong>这个集合会不会自动更新</strong>。</p> <p><strong>getEle会，queryS不会</strong></p> <h2 id="_28-async-与-promise-的区别"><a href="#_28-async-与-promise-的区别" class="header-anchor">#</a> 28.async 与 promise 的区别</h2> <ul><li>async/await让try/catch 可以同时处理同步和异步错误。</li> <li>Promise  then 中try/catch不能处理JSON.parse的错误</li></ul> <h2 id="_30-手写-call-apply-bind"><a href="#_30-手写-call-apply-bind" class="header-anchor">#</a> 30.手写 call apply bind</h2> <h3 id="call"><a href="#call" class="header-anchor">#</a> call</h3> <div class="language- line-numbers-mode"><pre class="language-text"><code>Function.prototype.myCall = function(context) {
  // 判断是否是undefined和null
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  context.fn = this
  let args = [...arguments].slice(1)
  let result = context.fn(...args)
  delete context.fn
  return result
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h3 id="apply"><a href="#apply" class="header-anchor">#</a> apply</h3> <div class="language- line-numbers-mode"><pre class="language-text"><code>Function.prototype.myApply = function(context) {
  if (typeof context === 'undefined' || context === null) {
    context = window
  }
  context.fn = this
  let args = arguments[1]
  let result
  if (args) {
    result = context.fn(...args)
  } else {
    result = context.fn()
  }
  delete context.fn
  return result
}

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><h3 id="bind"><a href="#bind" class="header-anchor">#</a> bind</h3> <div class="language- line-numbers-mode"><pre class="language-text"><code>Function.prototype.myBind = function(context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  let _this = this
  let args = [...arguments].slice(1)
  return function F() {
    // 判断是否被当做构造函数使用
    if (this instanceof F) {
      return _this.apply(this, args.concat([...arguments]))
    }
    return _this.apply(context, args.concat([...arguments]))
  }
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br></div></div><h2 id="_31-手写-promise"><a href="#_31-手写-promise" class="header-anchor">#</a> 31.手写 promise</h2> <div class="language- line-numbers-mode"><pre class="language-text"><code>        const PENDING = &quot;pending&quot;;//初始值，不是fulfilled，也不是rejected
        const FULFILLED = &quot;filfilled&quot;;//代表操作成功
        const REJECTED = &quot;rejected&quot;;//代表操作失败

        function myPromise(fn) {
            console.log(1);
            let that = this;
            that.state = PENDING;
            that.value = null;
            that.resolvedCallBacks = [];
            that.rejectedCallBacks = [];

            // 首先两个函数都得判断当前状态是否为等待中，因为规范规定只有等待态才可以改变状态
            // 将当前状态更改为对应状态，并且将传入的值赋值给 value
            // 遍历回调数组并执行

            function resolve(value) {
                console.log(2);

                if (that.state == PENDING) {
                    that.value = value;
                    that.resolvedCallBacks.map(cb =&gt; that.value);
                }
            };
            function reject(value) {
                console.log(3);

                if (that.state == PENDING) {
                    that.value = value;
                    that.rejectedCallBacks.map(cb =&gt; that.value);
                }
            };

            // 实现很简单，执行传入的参数并且将之前两个函数当做参数传进去
            // 要注意的是，可能执行函数过程中会遇到错误，需要捕获错误并且执行 reject 函数
            try {
                console.log(4);

                fn(resolve, reject)
            } catch (e) {
                console.log(5);

                reject(e)
            }
        }

        myPromise.prototype.then = function (onFulfilled, onRejected) {
            const that = this;
            console.log(6);
            // 首先判断两个参数是否为函数类型，因为这两个参数是可选参数
            // 当参数不是函数类型时，需要创建一个函数赋值给对应的参数，同时也实现了透传
            onFulfilled = typeof onFulfilled === &quot;function&quot; ? onFulfilled : v =&gt; v;
            onRejected = typeof onRejected === &quot;function&quot; ? onRejected : r =&gt; { throw r };
            // 接下来就是一系列判断状态的逻辑，当状态不是等待态时，就去执行相对应的函数。
            // 如果状态是等待态的话，就往回调函数中 push 函数
            if (that.state === PENDING) {
                that.resolvedCallBacks.push(onFulfilled);
                that.rejectedCallBacks.push(onRejected);
            }
            if (that.state === FULFILLED) {
                onFulfilled(that.value)
            }
            if (that.state === REJECTED) {
                onRejected(that.value)
            }
        }
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br></div></div><h3 id="调用"><a href="#调用" class="header-anchor">#</a> 调用</h3> <div class="language- line-numbers-mode"><pre class="language-text"><code>       new myPromise((resolve, reject) =&gt; {
            setTimeout(() =&gt; {
                resolve(1)
            }, 3000)
        }).then(res =&gt; {
            console.log(res)
            console.log(7)
        }, err =&gt; {
            console.log(8)
        })

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br></div></div><h2 id="_32-手写-防抖节流"><a href="#_32-手写-防抖节流" class="header-anchor">#</a> 32.手写 防抖节流</h2> <h3 id="防抖-某个函数在短时间内只执行最后一次。"><a href="#防抖-某个函数在短时间内只执行最后一次。" class="header-anchor">#</a> 防抖：某个函数在短时间内只执行最后一次。</h3> <p>函数被触发时，需要先延迟，在延迟的时间内，如果再次被触发，则取消之前的延迟，重新开始延迟。这样就能达到，只响应最后一次，其余的请求都过滤掉。</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>export const Debounce = (fn, t) =&gt; {
  const delay = t || 500;
  let timer;
  return function () {
    const args = arguments;

    if (timer) {
      clearTimeout(timer);
    }

    timer = setTimeout(() =&gt; {
      timer = null;
      fn.apply(this, args);
    }, delay);
  };
};
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br></div></div><h3 id="节流-某个函数在指定时间段内只执行第一次-直到指定时间段结束-周而复始。"><a href="#节流-某个函数在指定时间段内只执行第一次-直到指定时间段结束-周而复始。" class="header-anchor">#</a> 节流：某个函数在指定时间段内只执行第一次，直到指定时间段结束，周而复始。</h3> <div class="language- line-numbers-mode"><pre class="language-text"><code>export const throttle = (func, interval) =&gt; {
    let flag = null;
    return function(...args) {
        if (!flag) {
            flag = true;
            setTimeout(() =&gt; {
                flag = false;
                fn.call(this, ...args);
            }, interval);
        }
    }
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><h3 id="bfc-块级格式化上下文"><a href="#bfc-块级格式化上下文" class="header-anchor">#</a> BFC 块级格式化上下文</h3> <p>BFC是一个独立的布局环境，其中的元素布局是不受外界的影响，并且在一个BFC中，块盒与行盒（行盒由一行中所有的内联元素所组成）都会垂直的沿着其父元素的边框排列。</p> <p>一个HTML元素要创建BFC，则满足下列的任意一个或多个条件即可：</p> <ul><li>1、float的值不是none。</li> <li>2、position的值不是static或者relative。</li> <li>3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex</li> <li>4、overflow的值不是visible</li></ul> <h3 id="从url输入到页面加载过程"><a href="#从url输入到页面加载过程" class="header-anchor">#</a> 从URL输入到页面加载过程</h3> <p>流程：缓存 -&gt; DNS解析 -&gt; TCP三次握手 -&gt; HTTP请求 -&gt; 数据响应 -&gt; 页面渲染 -&gt; TCP四次挥手</p> <p>浏览器渲染：创建DOM树—创建StyleRules—创建Render树—布局Layout—绘制</p> <p>参考：<a href="https://www.cnblogs.com/daijinxue/p/6640153.html" target="_blank" rel="noopener noreferrer">从输入url到页面加载完成发生了什么？<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></div></div> <div class="page-edit"><div class="tags"><a href="/tags/?tag=%E9%9D%A2%E8%AF%95" title="标签">#面试</a></div> <div class="last-updated"><span class="prefix">最近更新时间：</span> <span class="time">2021/05/01 17:06:28</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/pages/ac34940436a4a/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">前端基础知识整理01</div></a> <a href="/pages/3cea8c7d5577f/" class="page-nav-centre page-nav-centre-next"><div class="tooltip">xdm 来当当前端面试官</div></a></div> <div class="page-nav"><p class="inner"><span class="prev">
        ←
        <a href="/pages/ac34940436a4a/" class="prev">前端基础知识整理01</a></span> <span class="next"><a href="/pages/3cea8c7d5577f/">xdm 来当当前端面试官</a>→
      </span></p></div></div></div> <div class="theme-vdoing-wrapper article-list bg-style-11"><div class="article-title"><a href="/archives/" class="fa fa-pencil-alt">
      最近更新
    </a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><div><a href="/pages/512f6ae339a31/"><div>【TypesScript主题月】5.7</div></a></div> <div class="date"><span>2021/05/06 00:00:00</span></div></dt></dl><dl><dd>02</dd> <dt><div><a href="/pages/136f8f068dffe/"><div>【React主题月】4月完结</div></a></div> <div class="date"><span>2021/04/30 00:00:00</span></div></dt></dl><dl><dd>03</dd> <dt><div><a href="/pages/55e7bb3eb7802/"><div>【算法打卡】先来一个波集合</div></a></div> <div class="date"><span>2021/04/22 00:00:00</span></div></dt></dl> <div class="more-box"><a href="/archives/" class="more"><i class="fas fa-angle-double-right"></i>前往更多 ...
      </a></div></div></div> <div class="comments-wrapper" style="display:none;"><!----></div></main></div> <div class="footer-wrapper" data-v-51417878 data-v-51417878><span class="footer-reco-theme" data-v-51417878><i class="iconfont reco-github" data-v-51417878></i> <a target="blank" href="https://github.com/alexwjj/alexwjj.github.io" data-v-51417878>alexwjj.github.io@5.0</a></span> <!----> <span class="footer-copyright" data-v-51417878><i class="iconfont reco-copyright" data-v-51417878></i> <a data-v-51417878><span data-v-51417878>俊劫</span> <span class="ml5" data-v-51417878>
          2018 - 2021
        </span></a></span> <span class="footer-view-site" data-v-51417878><i class="iconfont reco-eye" data-v-51417878></i> <span id="busuanzi_container_site_uv" data-v-51417878>
        访客数：<span id="busuanzi_value_site_uv" class="num" data-v-51417878>-</span></span> <span id="busuanzi_container_site_pv" class="ml5" data-v-51417878>
        访问量：<span id="busuanzi_value_site_pv" class="num" data-v-51417878>-</span></span></span> <!----></div> <!----></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-c6073ba8 data-v-c6073ba8><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-c6073ba8><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-c6073ba8></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-c6073ba8></path></svg></div><!----><div></div></div></div>
    <script src="/assets/js/app.070ad525.js" defer></script><script src="/assets/js/2.1d15da37.js" defer></script><script src="/assets/js/40.e59f0b3b.js" defer></script><script src="/assets/js/4.aab0e518.js" defer></script>
  </body>
</html>
